<?php 
const APPID = 'wxaec5450838ee1107';
const MCHID = '1488004782';
const KEY = '8934e7d15453e97507ef794cf7b0519d';
const APPSECRET = '6f1044d5aaaf507197584468144132eb';
    /**
     * 
     * 拼接签名字符串
     * @param array $urlObj
     * [url=home.php?mod=space&uid=67594]@Return[/url] 返回已经拼接好的字符串
     */
    function ToUrlParams($urlObj)
    {
            $buff = "";
            foreach ($urlObj as $k => $v)
            {
                if($k != "sign"){
                    $buff .= $k . "=" . $v . "&";
                }
            }
             
            $buff = trim($buff, "&");
            return $buff;
    }
    /**
     * 统一下单，WxPayUnifiedOrder中out_trade_no、body、total_fee、trade_type必填
     * appid、mchid、spbill_create_ip、nonce_str不需要填入
     * @param WxPayUnifiedOrder $inputObj
     * @param int $timeOut
     * @throws WxPayException
     * @return 成功时返回，其他抛异常
     */
    function unifiedOrder( $timeOut = 6)
    {   
        $datas = array();
        $datas['body'] = 'test';
        $datas['out_trade_no'] = '1234567890123456789012';//订单号
        $datas['total_fee'] = '1';
        $datas['time_start'] = date("YmdHis");
        $datas['time_expire'] = date("YmdHis", time() + 600);
        $datas['notify_url'] = 'http://p154v65220.iask.in/demo/example/write.php';
        $datas['trade_type'] = 'JSAPI';
        $datas['openid'] = 'oXhDqwVLStq9FBw_eThzUF5IQ_mM';
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";  
        $datas['appid'] = APPID;//公众账号ID
        $datas['mch_id'] = MCHID;//商户号
        $datas['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'];//ip  
        $datas['nonce_str'] = getNonceStr();//随机字符串 
        //签名步骤一：按字典序排序参数
        ksort($datas);
        $string = ToUrlParamss($datas);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=".KEY;
      
        //签名步骤三：MD5加密
        $string = md5($string);
         //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        $datas['sign'] = $result;//签名 
        $xml = ToXml($datas);
        $response = postXmlCurl($xml, $url, false, $timeOut);
        $data = FromXml($response);
        var_dump($data);
        return $data;
    }
    /**
     * 产生随机字符串，不长于32位
     * @param int $length
     * @return 产生的随机字符串
     */
    function getNonceStr($length = 32) 
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {  
            $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
        } 
        return $str;
    }
    /**
     * 输出xml字符
    **/
    function ToXml($datas)
    {   
        $xml = "<xml>";
        foreach ($datas as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml; 
    }
    /**
     * 格式化参数格式化成url参数
     */
    function ToUrlParamss($datas)
    {
        $buff = "";
        foreach ($datas as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
    /**
     * 以post方式提交xml到对应的接口url
     * 
     * @param string $xml  需要post的xml数据
     * @param string $url  url
     * @param bool $useCert 是否需要证书，默认不需要
     * @param int $second   url执行超时时间，默认30s
     */
    function postXmlCurl($xml, $url, $useCert = false, $second = 30)
    {       
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);//严格校验
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
 
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        curl_close($ch);
        return $data;
    }
    /**
     * 将xml转为array
     * @param string $xml
     */
    function FromXml($xml)
    {   
        if(!$xml){
            echo "xml数据异常！";
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);       
        return $data;
    }
    /**
     * 获取jsapi支付的参数
     * @param array $UnifiedOrderResult 统一支付接口返回的数据
     * @return json数据，可直接填入js函数作为参数
     */
    function GetJsApiParameters(){
        $UnifiedOrderResult = unifiedOrder();
        if(!array_key_exists("appid", $UnifiedOrderResult)
        || !array_key_exists("prepay_id", $UnifiedOrderResult)
        || $UnifiedOrderResult['prepay_id'] == "")
        {
          echo "参数错误";
            exit;
        }
        $da = array();
        $da['appId'] = $UnifiedOrderResult["appid"];
        $timeStamp = time();
        $da['timeStamp'] = "$timeStamp";
        $da['nonceStr'] = getNonceStr();
        $da['package'] = "prepay_id=" . $UnifiedOrderResult['prepay_id'];
        $da['signType'] = 'MD5';
        //签名步骤一：按字典序排序参数
        ksort($da);
        $string = ToUrlParamss($da);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=".KEY;
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        $da['paySign'] = $result;
        $parameters = json_encode($da);
        return $parameters;
    }
    unifiedOrder();
    exit;
    $da = GetJsApiParameters();
    var_dump($da);
 ?>
 <html>
 <head>
     <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
     <meta name="viewport" content="width=device-width, initial-scale=1"/> 
     <title>微信h5支付-王文晓</title>
     <script type="text/javascript">
   //调用微信JS api 支付
   function jsApiCall()
   {
       WeixinJSBridge.invoke(
           'getBrandWCPayRequest',
           <?php echo $da; ?>,
           function(res){
               WeixinJSBridge.log(res.err_msg);
               alert(res.err_code+res.err_desc+res.err_msg);
           }
       );
   }
   function callpay()
   {
       if (typeof WeixinJSBridge == "undefined"){
           if( document.addEventListener ){
               document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
           }else if (document.attachEvent){
               document.attachEvent('WeixinJSBridgeReady', jsApiCall); 
               document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
           }
       }else{
           jsApiCall();
       }
   }
   </script>
 </head>
 <body>
     <br/>
     <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px">1分</span>钱</b></font><br/><br/>
   <div align="center">
       <button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:16px;" type="button" onclick="callpay()" >立即支付</button>
   </div>
 </body>
 </html>